package cn.kerui.manage.service.role.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.kerui.common.core.constant.Constants;
import cn.kerui.common.core.domain.CommonResult;
import cn.kerui.common.exception.ServiceException;
import cn.kerui.common.framework.util.lang.CollectionUtil;
import cn.kerui.common.framework.util.validation.Assert;
import cn.kerui.common.core.PageResult;
import cn.kerui.manage.service.role.RoleService;
import cn.kerui.manage.vo.role.PageRoleModel;
import cn.kerui.manage.vo.role.RolePermsVo;
import cn.kerui.manage.vo.role.RoleVo;
import cn.kerui.repos.entities.manage.ManageRole;
import cn.kerui.repos.entities.manage.ManageRoleMenu;
import cn.kerui.repos.mapper.manage.ManageRoleMapper;
import cn.kerui.repos.mapper.manage.ManageRoleMenuMapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 角色业务层实现
 * <p>创建于 2024/2/6 20:07 </p>
 *
 * @author yangkai
 * @version v1.0
 * @since 1.0.0
 */
@Service
@AllArgsConstructor
@Slf4j
public class RoleServiceImpl implements RoleService {


    private ManageRoleMapper manageRoleMapper;

    private ManageRoleMenuMapper manageRoleMenuMapper;

    private SqlSessionTemplate sqlSessionTemplate;

    /**
     * 分页查询角色信息
     *
     * @param model
     * @return
     */
    @Override
    public PageResult<RoleVo> page(PageRoleModel model) {
        // 分页查询顶级角色列表
        // TODO 根据当前登陆用户角色查询可展示的角色信息
        PageResult<ManageRole> page = PageResult.Plus.page(model.getPage(), model.getSize(),
                t -> manageRoleMapper.selectPage(t, new LambdaQueryWrapper<>(ManageRole.class)
                        .eq(ManageRole::getParentId, 0L)));

        log.info("分页查询角色信息成功, result = {}", JSON.toJSONString(page));

        PageResult<RoleVo> collect = page.map(t -> BeanUtil.copyProperties(t, RoleVo.class));
        // 遍历查询所有子角色信息
        collect.forEach(t -> {
            List<ManageRole> manageRoles = manageRoleMapper.selectRoleWithChild(t.getId());
            List<RoleVo> roleVos = BeanUtil.copyToList(manageRoles, RoleVo.class);
            t.setChildRoles(roleVos);
        });

        return collect;
    }

    /**
     * 创建用户信息
     *
     * @param role
     * @return
     */
    @Override
    public CommonResult<Integer> save(ManageRole role) {
        Assert.isNotBlank(role.getRoleName(), () -> new ServiceException("角色名称不能为空"));
        Optional.ofNullable(role.getSort())
                .or(Constants.SORT_MAX::describeConstable)
                .ifPresent(role::setSort);

        int count = manageRoleMapper.insert(role);
        if (count < 0) {
            throw new ServiceException("创建角色失败");
        }
        return CommonResult.okResult(count);
    }

    /**
     * 更新角色信息
     *
     * @param role
     * @return
     */
    @Override
    public CommonResult<Integer> update(ManageRole role) {
        Assert.isNotEmpty(role.getId(), () -> new ServiceException("未查询到角色信息"));

        Long id = manageRoleMapper.selectCount(new QueryWrapper<>(ManageRole.class).eq("id", role.getId()));
        Assert.isTrue(id > 0, () -> new ServiceException("未查询到角色信息"));

        int count = manageRoleMapper.updateById(role);
        if (count < 0) {
            throw new ServiceException("更新角色失败");
        }
        return CommonResult.okResult(count);
    }

    @Override
    public CommonResult<?> savePerms(RolePermsVo vo) {
        List<Long> menuId = vo.getMenuId();
        Assert.isNotEmpty(menuId, () -> new ServiceException("未查询到菜单信息"));
        List<ManageRoleMenu> roleMenus = menuId.stream().map(t -> new ManageRoleMenu(vo.getRoleId(), t)).toList();

        // TODO 批量插入
        int i = manageRoleMenuMapper.insertOrUpdateBatch(roleMenus);
        if (i >= 0) {
            return CommonResult.okResult();
        }
        return CommonResult.error();
    }

    @Override
    public CommonResult<?> deletePerms(Long roleId, Long menuId) {
        // 递归查询所有子角色
        List<Long> roleIds = queryAllSubRole(roleId);

        // 查询所有拥有此权限的角色ID
        List<ManageRoleMenu> manageRoleMenus = manageRoleMenuMapper.selectList(new LambdaQueryWrapper<ManageRoleMenu>()
                .select(ManageRoleMenu::getId)
                .eq(ManageRoleMenu::getMenuId, menuId)
                .in(ManageRoleMenu::getRoleId, roleIds));

        if (CollectionUtil.isEmpty(manageRoleMenus)) {
            return CommonResult.okResult();
        }

        List<Long> ids = manageRoleMenus.stream().map(ManageRoleMenu::getId).toList();
        int count = manageRoleMenuMapper.deleteBatchIds(ids);
        if (count >= 1) {
            return CommonResult.okResult();
        }
        return CommonResult.error();
    }

    private List<Long> queryAllSubRole(Long roleId) {
        List<ManageRole> manageRoles = manageRoleMapper.selectRoleWithChild(roleId);
        if (CollectionUtil.isEmpty(manageRoles)) {
            return new ArrayList<>();
        }
        List<Long> list = manageRoles.stream().map(ManageRole::getId).toList();
        List<Long> roleIds = new ArrayList<>(list);
        for (Long id : list) {
            roleIds.addAll(queryAllSubRole(id));
        }
        return roleIds;
    }
}
